import { LoadingOutlined, PlusOutlined } from '@ant-design/icons';
import type { GetProp, UploadProps } from 'antd';
import { Form, Input, Modal, Select, TreeSelect, Upload } from 'antd';
import { useImperativeHandle, useState } from 'react';

import deptsApi from '@/api/deptsApi';
import rolesApi from '@/api/rolesApi';
import usersApi from '@/api/usersApi';
import { message } from '@/components/AntdGlobal';
import { baseURL } from '@/http/request';
import { IDept, IRole, IUser } from '@/types/api';
import { IAction, IModalProp } from '@/types/modal';
import storage from '@/utils/storage';

type FileType = Parameters<GetProp<UploadProps, 'beforeUpload'>>[0];

const CreateUser = (props: IModalProp<IUser.UserItem>) => {
    /* 数据管理 ---------------------------------------------------*/
    const [visible, setVisible] = useState(false);
    const [action, setAction] = useState<IAction>('create');
    const [form] = Form.useForm();
    const [roleList, setRoleList] = useState<IRole.RoleItem[]>([]);
    const [deptList, setDeptList] = useState<IDept.DeptItem[]>([]);
    const [userImg, setUserImg] = useState('');
    const [loading, setLoading] = useState(false);
    useImperativeHandle(props.mRef, () => {
        return {
            openModal
        };
    }); // 暴露子组件open方法，供父组件中调用props.mRef?.openModal()方法

    /* 逻辑代码 ---------------------------------------------------*/
    /**弹框显示
     * @param action 类型
     * @param data 数据
     */
    const openModal = (action: IAction, data?: IUser.UserItem) => {
        setAction(action);
        setVisible(true);
        // 数据时效性，每次打开弹窗时重新获取数据
        getAllRoleList();
        getDeptList();
        // 编辑时，表单赋值
        if (action === 'edit' && data) {
            form.setFieldsValue({ ...data });
            setUserImg(data.userImg);
        }
    };

    /**获取部门列表
     */
    const getDeptList = async () => {
        const { data } = await deptsApi.getDeptsList();
        setDeptList(data);
    };

    /**获取角色列表
     */
    const getAllRoleList = async () => {
        const { data } = await rolesApi.getAllRoleList();
        setRoleList(data);
    };

    /**头像上传之前接口处理
     */
    const beforeUpload = (file: FileType) => {
        const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
        if (!isJpgOrPng) {
            message.error('只能上传png或jpeg格式的图片');
            return false;
        }
        const isLt500K = file.size / 1024 / 1024 < 2;
        if (!isLt500K) {
            message.error('图片不能超过2M');
        }
        return isJpgOrPng && isLt500K;
    };

    /**头像上传之后处理
     */
    const handleChange: UploadProps['onChange'] = (info) => {
        if (info.file.status === 'uploading') {
            setLoading(true);
            return;
        }

        if (info.file.status === 'done') {
            setLoading(false);
            const { code, data, msg } = info.file.response;
            if (code === '000000') {
                setUserImg(data.file);
                message.success('上传成功');
            } else {
                message.error(msg);
            }
        } else if (info.file.status === 'error') {
            setLoading(false);
            message.error('服务器异常，请稍后重试');
        }
    };

    /**表单提交
     */
    const handleSubmit = async () => {
        try {
            const valid = await form.validateFields();
            if (valid) {
                const data = {
                    ...form.getFieldsValue(),
                    userImg
                };
                if (action === 'create') {
                    await usersApi.createUser(data);
                    message.success('创建成功');
                } else if (action === 'edit') {
                    await usersApi.editUser(data);
                    message.success('修改成功');
                }
                // 关闭弹窗，重置表单数据
                handleCancel();
                // 父组件更新列表
                props.update();
            }
        } catch (error) {
            console.error(error);
        }
    };

    /**取消操作
     */
    const handleCancel = () => {
        setVisible(false);
        // 重置表单时机：退出时重置 优于 打开时判断重置
        form.resetFields();
        setUserImg('');
    };

    return (
        <Modal
            title={action === 'create' ? '创建用户' : '编辑用户'}
            width={800}
            open={visible}
            okText="确定"
            cancelText="取消"
            onOk={handleSubmit}
            onCancel={handleCancel}
        >
            <Form
                form={form}
                labelCol={{
                    span: 4
                }}
                labelAlign="right"
            >
                {/* 隐藏提交项,edit时提交 */}
                <Form.Item
                    name="userId"
                    hidden
                >
                    <Input />
                </Form.Item>
                <Form.Item
                    label="用户名称"
                    name="userName"
                    rules={[
                        { required: true, message: '请输入用户名称' },
                        {
                            min: 4,
                            max: 12,
                            message: '用户名称最小5个字符，最大12个字符'
                        }
                    ]}
                >
                    <Input placeholder="请输入用户名称" />
                </Form.Item>
                <Form.Item
                    label="用户邮箱"
                    name="userEmail"
                    rules={[
                        { required: true, message: '请输入用户邮箱' },
                        { type: 'email', message: '请输入正确的邮箱' },
                        {
                            pattern: /^\w+@outlook.com$/,
                            message: '邮箱必须以@outlook.com结尾'
                        }
                    ]}
                >
                    <Input
                        placeholder="请输入用户邮箱"
                        disabled={action === 'edit'}
                    />
                </Form.Item>
                <Form.Item
                    label="手机号"
                    name="mobile"
                    rules={[
                        { len: 11, message: '请输入11位手机号' },
                        {
                            pattern: /1[1-9]\d{9}/,
                            message: '请输入1开头的11位手机号'
                        }
                    ]}
                >
                    <Input
                        type="number"
                        placeholder="请输入手机号"
                    />
                </Form.Item>
                <Form.Item
                    label="部门"
                    name="deptId"
                    rules={[
                        {
                            required: true,
                            message: '请选择部门'
                        }
                    ]}
                >
                    <TreeSelect
                        placeholder="请选择部门"
                        allowClear
                        treeDefaultExpandAll
                        showCheckedStrategy={TreeSelect.SHOW_ALL}
                        fieldNames={{ label: 'deptName', value: 'deptId' }}
                        treeData={deptList}
                    />
                </Form.Item>
                <Form.Item
                    label="岗位"
                    name="job"
                >
                    <Input placeholder="请输入岗位" />
                </Form.Item>
                <Form.Item
                    label="状态"
                    name="state"
                >
                    <Select>
                        <Select.Option value="1">在职</Select.Option>
                        <Select.Option value="2">离职</Select.Option>
                        <Select.Option value="3">试用期</Select.Option>
                    </Select>
                </Form.Item>
                <Form.Item
                    label="系统角色"
                    name="roleList"
                    rules={[
                        {
                            required: true,
                            message: '请选择系统角色',
                            type: 'array'
                        }
                    ]}
                >
                    <Select
                        placeholder="请选择角色"
                        mode="multiple"
                        allowClear
                    >
                        {roleList.map((item) => {
                            return (
                                <Select.Option
                                    value={item.roleId}
                                    key={item.roleId}
                                >
                                    {item.roleName}
                                </Select.Option>
                            );
                        })}
                    </Select>
                </Form.Item>
                <Form.Item label="用户头像">
                    <Upload
                        listType="picture-circle"
                        showUploadList={false}
                        headers={{
                            Authorization: 'Bearer ' + storage.get('token')
                        }}
                        action={`${baseURL}/users/upload`}
                        beforeUpload={beforeUpload}
                        onChange={handleChange}
                    >
                        {userImg ? (
                            <img
                                src={userImg}
                                style={{ width: '100%', borderRadius: '50%' }}
                            />
                        ) : (
                            <div>
                                {loading ? <LoadingOutlined /> : <PlusOutlined />}
                                <div style={{ marginTop: 5 }}>上传头像</div>
                            </div>
                        )}
                    </Upload>
                </Form.Item>
            </Form>
        </Modal>
    );
};

export default CreateUser;
